package main

import (
	"bytes"
	"context"
	"crypto/rand"
	"crypto/rsa"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/big"
	"net/http"
	"net/url"
	"regexp"
	"strconv"
	"strings"
	"time"
)

// WeboAccount 对应一个已登陆的微博账号
type WeboAccount struct {
	Account  string
	Password string
	Online   bool
	Cookie   []*http.Cookie
	Context  context.Context
}

func (wba *WeboAccount) dePassword(servertime int64, nonce, pubkey string) string {
	// var reaE int
	reaN := new(big.Int)

	reaE, err := strconv.ParseInt("10001", 16, 0)
	if err != nil {
		fmt.Print(err)
		return ""
	}

	rean, ok := reaN.SetString(pubkey, 16)
	if !ok {
		fmt.Print(ok)
		return ""
	}

	pwString := strconv.FormatInt(servertime, 10) + "\t" + nonce + "\n" + wba.Password
	publicKey := &rsa.PublicKey{N: rean, E: int(reaE)}

	pwEncypted, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, []byte(pwString))
	if err != nil {
		fmt.Print(err)
		return ""
	}
	fmt.Println(string(pwEncypted))

	// pw_encypted = rsa.encrypt(pw_string.encode('utf-8'), key)

	// password = ''  # 安全起见清空明文密码
	// passwd = binascii.b2a_hex(pw_encypted)  #将二进制编码转化为ascii/hex
	// rsa.
	return ""
}
func (wba *WeboAccount) deAccount() string {
	//base64 加密用户名
	var encoded bytes.Buffer
	encoder := base64.NewEncoder(base64.StdEncoding, &encoded)
	encoder.Write([]byte(wba.Account))
	encoder.Close()
	return encoded.String()
}

// WeiBo 一条微博
type WeiBo struct {
	Text string
}

// PreRequest 返回的数据
type PreRequest struct {
	ServerTime int64  `json:"servertime"`
	Nonce      string `json:"nonce"`
	Pubkey     string `json:"pubkey"`
	Rsakv      string `json:"rsakv"`
}

// Login 基础登陆
func (wba *WeboAccount) Login() (bool, error) {

	// func vister(){}
	// func first(){}
	// func prelogin(){}
	// func password(){}
	// func login(){}
	// func home(){}

	// 第一步
	fmt.Println("预登录中...")
	onereq, err := http.NewRequest("GET", "https://login.sina.com.cn/sso/prelogin.php", nil)
	if err != nil {
		fmt.Println(err)
	}
	query := onereq.URL.Query()
	query.Add("entry", "weibo")
	query.Add("callback", "sinaSSOController.preloginCallBack")
	query.Add("su", wba.enAccount())
	query.Add("rsakt", "mod")
	query.Add("client", "ssologin.js(v1.4.19)")
	query.Add("_", strconv.FormatInt(time.Now().UnixNano()/1e6, 10))
	onereq.URL.RawQuery = query.Encode()
	resp, err := http.DefaultClient.Do(onereq)
	if err != nil {
		fmt.Println(err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
	}

	reg := regexp.MustCompile(`^sinaSSOController.preloginCallBack\((.*?)\)`)
	date := reg.FindStringSubmatch(string(body))

	pr := &PreRequest{}
	juerr := json.Unmarshal([]byte(date[1]), pr)
	if juerr != nil {
		fmt.Println(juerr)
	}
	fmt.Printf("%s\n", string(body))
	fmt.Println("预登录完成!!!")

	// 第二步
	fmt.Println("正式登录中.....")

	towformdate := url.Values{}
	towformdate.Add("su", wba.deAccount())
	towformdate.Add("sp", wba.dePassword(pr.ServerTime, pr.Nonce, pr.Pubkey))
	towformdate.Add("servertime", strconv.FormatInt(time.Now().UnixNano()/1e6, 10))
	towformdate.Add("nonce", pr.Nonce)
	towformdate.Add("rsakv", pr.Rsakv)

	towformdate.Add("useticket", "1")
	towformdate.Add("entry", "weibo")
	towformdate.Add("gateway", "1")
	towformdate.Add("from", "")
	towformdate.Add("savestate", "7")
	towformdate.Add("qrcode_flag", "false")
	towformdate.Add("useticket", "1")
	towformdate.Add("pagerefer", "https://weibo.com/")
	towformdate.Add("vsnf", "1")
	towformdate.Add("service", "miniblog")
	towformdate.Add("pwencode", "rsa2")
	towformdate.Add("sr", "1920*1080")
	towformdate.Add("encoding", "UTF-8")
	towformdate.Add("prelt", "117")
	towformdate.Add("url", "https://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack")
	towformdate.Add("returntype", "META")

	towreq, err := http.NewRequest("POST", "https://login.sina.com.cn/sso/login.php", strings.NewReader(towformdate.Encode()))
	if err != nil {
		fmt.Println(err)
	}
	towquery := towreq.URL.Query()
	towquery.Add("client", "ssologin.js(v1.4.19)")
	query.Add("_", strconv.FormatInt(time.Now().UnixNano()/1e6, 10))
	towreq.URL.RawQuery = towquery.Encode()

	towresp, err := http.DefaultClient.Do(towreq)
	if err != nil {
		fmt.Println(err)
	}
	defer towresp.Body.Close()
	towbody, err := ioutil.ReadAll(towresp.Body)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(string(towbody))
	fmt.Println("正式登录完成!!!")
	return false, nil
}

// LogOut 基础登陆
func (wba *WeboAccount) LogOut() (bool, error) {
	return false, nil
}

// Check 检查登录状态
func (wba *WeboAccount) Check() (bool, error) {
	return false, nil
}

// PushWeiBo 发送一条微博
func (wba *WeboAccount) PushWeiBo(WeiBo) (bool, error) {
	return false, nil
}

// DelWeiBo 删除一条微博
func (wba *WeboAccount) DelWeiBo(WeiBo) (bool, error) {
	return false, nil
}
